import React, { PureComponent, Fragment } from 'react';
import {
  Card,
  Table,
  Button,
  Spin,
  Tree,
  Icon,
  Form,
  Modal,
  Input,
  Divider,
} from 'antd';
import { connect } from 'dva';
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import styles from "./Role.less";

const FormItem = Form.Item;
const { TreeNode } = Tree;

@connect(({ authMenu, authRole, loading }) => ({
  authMenu,
  authRole,
  loading: loading.models.authMenu,
}))
@Form.create()
class UpdateMenuTree extends PureComponent {

  onCheck = (checkedKeys) => {
    console.log(checkedKeys)
    const { dispatch } = this.props;
    dispatch({
      type: 'authRole/changeMenuIds',
      payload: checkedKeys
    })

  }

  okHandle = () => {
    const { handleUpdateMenu, values, authRole: { menuIds } } = this.props;
    if (values && Object.keys(values).length) {
      handleUpdateMenu(values.roleId, menuIds);
    }
  }



  render() {
    const { updateMenuModalVisible, authMenu: { list }, authRole: { menuIds }, handleUpdateMenuModalVisible, values } = this.props;
    return (
      <Modal
        destroyOnClose
        title="更新菜单权限"
        visible={updateMenuModalVisible}
        onOk={this.okHandle}
        onCancel={() => handleUpdateMenuModalVisible(false)}
        width={300}
        bodyStyle={{ padding: '32px 40px 48px' }}
      >
        {
          !list.length ? <Spin /> : (
            <Tree
              checkable
              showIcon
              defaultExpandAll
              checkedKeys={menuIds}
              onCheck={this.onCheck}
            >
              {list && Object.keys(list).length ?
                (list.map(levelOne => (
                  <TreeNode icon={<Icon type={levelOne.icon} />} title={levelOne.menuDesc} key={levelOne.menuId}>
                    {levelOne.children && Object.keys(levelOne.children).length ? (
                      levelOne.children.map(levelTwo => (
                        <TreeNode icon={<Icon type={levelTwo.icon} />} title={levelTwo.menuDesc} key={levelTwo.menuId} />
                      ))
                    ) : null}
                  </TreeNode>
                )
                )) : null}
            </Tree>
          )}
      </Modal>
    );
  }
}

/**
 * 新增或编辑角色组件, 根据传值与否控制
 */
@connect(({ authRole, loading }) => ({
  authRole,
  loading: loading.models.authRole,
}))
@Form.create()
class AddOrUpdateForm extends PureComponent {

  okHandle = () => {
    const { form, handleAdd, handleUpdate, values } = this.props;
    form.validateFields((err, fieldsValue) => {
      if (err) return;
      if (values && Object.keys(values).length) {
        handleUpdate(fieldsValue)
      } else {
        handleAdd(fieldsValue);
      }
    });
  }

  render() {
    const { modalVisible, form, handleModalVisible, values } = this.props;
    return (
      <Modal
        destroyOnClose
        title={values && Object.keys(values).length ? "编辑角色" : "新增角色"}
        visible={modalVisible}
        onOk={this.okHandle}
        onCancel={() => handleModalVisible(false)}
      >
        <Form>
          <div>
            {form.getFieldDecorator('roleId', {
              initialValue: values && Object.keys(values).length ? values.roleId : null
            })(
              <Input type="hidden" />
            )}
          </div>
          <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="角色名">
            {form.getFieldDecorator('roleName', {
              initialValue: values && Object.keys(values).length ? values.roleName : null,
              rules: [{ required: true, message: '角色名必填！' }],
            })(
              <Input />
            )}
          </FormItem>
          <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="角色描述">
            {form.getFieldDecorator('roleDesc', {
              initialValue: values.roleDesc,
              rules: [{ required: true, message: '角色描述必填' }],
            })(
              <Input />
            )}
          </FormItem>
        </Form>
      </Modal>
    );
  }
}

/* eslint react/no-multi-comp:0 */
@connect(({ authRole, loading }) => ({
  authRole,
  loading: loading.models.authRole,
}))
class RoleList extends PureComponent {
  state = {
    modalVisible: false,
    updateMenuModalVisible: false,
    selectedRowKeys: [],
    stepFormValues: {},
    stepTreeValues: {}
  };


  columns = [
    {
      title: '角色名',
      dataIndex: 'roleName'
    },
    {
      title: '角色描述',
      dataIndex: 'roleDesc'
    },
    {
      title: '操作',
      width: 200,
      render: (text, record) => (
        <Fragment>
          <a onClick={() => this.handleModalVisible(true, record)}>编辑</a>
          <Divider type="vertical" />
          <a onClick={() => this.handleUpdateMenuModalVisible(true, record)}>权限</a>
          <Divider type="vertical" />
          <a onClick={() => this.handleDel(record)}>删除</a>
        </Fragment>
      ),
    },
  ];

  componentDidMount() {
    const { authRole: { data } } = this.props;
    this.pageRoles(data.size, data.current)
    this.fetchMenuTree();
  }

  /**
   * 表格多选
   */
  handleSelectRows = selectedRowKeys => {
    console.log(selectedRowKeys)
    this.setState({
      selectedRowKeys,
    });
  };

  /**
   * 控制编辑模态
   */
  handleModalVisible = (flag, record) => {
    this.setState({
      modalVisible: !!flag,
      stepFormValues: record || {},
    });
  };

  /**
   * 控制编辑模态
   */
  handleUpdateMenuModalVisible = (flag, record) => {
    this.setState({
      updateMenuModalVisible: !!flag,
      stepTreeValues: record || {},
    });

    if (record) {
      this.fetchMenuIds(record.roleId)
    }
  };

  /**
   * 新增
   */
  handleAdd = fields => {
    const { dispatch } = this.props;
    console.log(fields)
    dispatch({
      type: 'authRole/add',
      payload: {
        ...fields
      },
    })
    this.handleModalVisible();
  };

  /**
   * 更新
   */
  handleUpdate = fields => {
    const { dispatch } = this.props;
    dispatch({
      type: 'authRole/update',
      payload: {
        ...fields
      },
    })
    this.handleModalVisible();
  };

  /**
   * 更新
   */
  handleUpdateMenu = (roleId, menuIds) => {
    const { dispatch } = this.props;
    dispatch({
      type: 'authRole/updateMenuIds',
      payload: {
        roleId,
        menuIds
      },
    });

    this.handleUpdateMenuModalVisible();
  };


  /**
   * 批量删除
   */
  handleDelBatch = (selectedRowKeys) => {

    const that = this;
    Modal.confirm({
      title: `确定删除选中的 ${selectedRowKeys.length} 项 ?`,
      okText: "确认",
      cancelText: "取消",
      onOk() {
        that.props.dispatch({
          type: 'authRole/delBatch',
          payload: selectedRowKeys
        })
      },
      onCancel() { },
    });
  }

  /**
   * 删除
   */
  handleDel = (record) => {
    const that = this;
    Modal.confirm({
      title: `确定删除此项 ?`,
      okText: "确认",
      cancelText: "取消",
      onOk() {
        that.props.dispatch({
          type: 'authRole/del',
          payload: {
            uid: record.uid
          }
        })
      },
      onCancel() { },
    });
  }

  /**
   * 获取分页数据
   * @param {*} pageIndex 
   * @param {*} pageSize 
   */
  pageRoles = (pageSize, pageIndex) => {
    const { dispatch } = this.props;
    dispatch({
      type: 'authRole/page',
      payload: {
        pageIndex,
        pageSize
      }
    })
  }

  /**
   * 根据角色id获取菜单id列表
   */
  fetchMenuIds(roleId) {
    const { dispatch } = this.props;
    dispatch({
      type: 'authRole/listMenuIds',
      payload: roleId
    })
  }

  /**
   * 获取菜单列表
   */
  fetchMenuTree() {
    const { dispatch } = this.props;
    dispatch({
      type: 'authMenu/list'
    })
  }

  /**
   * 切换显示
   * @param {*} current 
   */
  changePage(current) {
    const { authRole: { data } } = this.props;
    this.pageRoles(data.size, current)
  }

  /**
   * 切换显示数量
   * @param {*} pageSize 
   * @param {*} current 
   */
  changePageSize(pageSize, current) {
    this.pageRoles(pageSize, current)
  }

  render() {
    const { loading, authRole: { data } } = this.props;

    const {
      selectedRowKeys,
      modalVisible,
      updateMenuModalVisible,
      stepFormValues,
      stepTreeValues
    } = this.state;

    const rowSelection = {
      selectedRowKeys,
      onChange: this.handleSelectRows
    };

    // 分页配置
    const pagination = {
      showSizeChanger: true,
      showQuickJumper: false,
      showTotal: () => `共${data.total}条`,
      pageSize: data.size,
      current: data.current,
      total: data.total,
      records: data.total,
      onShowSizeChange: (currentPage, newPageSize) => this.changePageSize(newPageSize, currentPage),
      onChange: (currentPage) => this.changePage(currentPage),
    };

    const parentMethods = {
      handleModalVisible: this.handleModalVisible,
      handleUpdate: this.handleUpdate,
      handleAdd: this.handleAdd,
    };

    const updateParentMethods = {
      handleUpdateMenuModalVisible: this.handleUpdateMenuModalVisible,
      handleUpdateMenu: this.handleUpdateMenu,
    };

    return (
      <PageHeaderWrapper title="角色管理">
        <Card bordered={false}>
          <div className={styles.tableList}>
            <div className={styles.tableListOperator}>
              <Button icon="plus" type="primary" onClick={() => this.handleModalVisible(true)}>
                新建
              </Button>
              {selectedRowKeys.length > 0 && (
                <span>
                  <Button icon="delete" onClick={() => this.handleDelBatch(selectedRowKeys)}>删除</Button>
                </span>
              )}
            </div>
            <Table
              rowSelection={rowSelection}
              loading={loading}
              dataSource={data.records}
              columns={this.columns}
              rowKey="roleId"
              pagination={pagination}
            />
          </div>
        </Card>
        <AddOrUpdateForm
          {...parentMethods}
          modalVisible={modalVisible}
          values={stepFormValues}
        />
        <UpdateMenuTree
          {...updateParentMethods}
          updateMenuModalVisible={updateMenuModalVisible}
          values={stepTreeValues}
        />
      </PageHeaderWrapper>
    )
  }
}

export default RoleList;